#include "focus_evaluation.h"

using namespace std;
using namespace cv;

void FocusEvaluation::selectRegion(const cv::Mat& image, cv::Mat& region, const cv::Size& regionSize)
{
	if (image.empty()) {
		return;
	}

	int rows = image.rows, cols = image.cols;
	int regionRows = regionSize.height, regionCols = regionSize.width;

	if (regionRows > rows || regionCols > cols) {
		return;
	}

	int center_x = cols / 2, center_y = rows / 2;
	region = image({ center_y - regionRows / 2, center_y + regionRows / 2 },
		{ center_x - regionCols / 2, center_x + regionCols / 2 });
}

double FourierEvaluation::evaluate(const cv::Mat& image)
{
	if (image.empty()) {
		return 0;
	}

	Mat grayImage = image;
	if (grayImage.channels() != 1) {
		cvtColor(grayImage, grayImage, COLOR_BGR2GRAY);
	}

	Mat region;
	selectRegion(grayImage, region, { grayImage.cols, grayImage.rows });

	region = Mat_<float>(region);

	// size is 2^n, not to do fourier optimizer
	Mat complexImage;
	dft(region, complexImage, DFT_COMPLEX_OUTPUT);

	vector<Mat> fourierImages;
	split(complexImage, fourierImages);

	magnitude(fourierImages[0], fourierImages[1], fourierImages[0]);

	return sum(fourierImages[0])[0];
}

double VarianceEvaluation::evaluate(const cv::Mat& image)
{
	if (image.empty()) {
		return 0;
	}

	Mat grayImage = image;
	if (grayImage.channels() != 1) {
		cvtColor(grayImage, grayImage, COLOR_BGR2GRAY);
	}

	Mat region;
	selectRegion(grayImage, region, { 512, 512 });

	Scalar mean, stddev;
	meanStdDev(region, mean, stddev);

	return stddev[0];
}

